package com.lagou.handler;

import com.alibaba.fastjson.JSON;
import com.lagou.protocol.NodeInfo;
import com.lagou.protocol.RpcRequest;
import com.lagou.protocol.RpcResponse;
import com.lagou.util.SpringBeanUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.apache.curator.framework.CuratorFramework;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Random;

public class UserServerHandler extends ChannelInboundHandlerAdapter {
    private CuratorFramework curatorClient;
    private String path;
    private Random random = new Random();

    public UserServerHandler(CuratorFramework curatorClient,  String path) {
        this.curatorClient = curatorClient;
        this.path = path;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            // 获取class
            RpcRequest rpcRequest = (RpcRequest) msg;
            String className = rpcRequest.getClassName();
            Class<?> aClass = Class.forName(className);

            // 获取bean对象
            Object bean = SpringBeanUtil.getBean(aClass);

            // 获取要执行的方法
            String methodName = rpcRequest.getMethodName();
            Class<?>[] parameterTypes = rpcRequest.getParameterTypes();
            Method method = aClass.getDeclaredMethod(methodName, parameterTypes);

            // 执行方法
            Object result = method.invoke(bean, rpcRequest.getParameters());

            // 向zk写入一个1-5的随机数字和写入时间
            byte[] bytes = curatorClient.getData().forPath(path);
            NodeInfo nodeInfo = JSON.parseObject(bytes, NodeInfo.class);
            nodeInfo.setLastModified((new Date()).getTime());
            nodeInfo.setResponseTime(random.nextInt(5)+1);
            curatorClient.setData().forPath(path, JSON.toJSONBytes(nodeInfo));

            // 构造返回体
            RpcResponse rpcResponse = new RpcResponse();
            rpcResponse.setResult(result.toString());
            rpcResponse.setThreadInfo(rpcRequest.getThreadInfo());
            ctx.writeAndFlush(rpcResponse);
        } catch (Exception e) {
            e.printStackTrace();
            ctx.writeAndFlush(e.getMessage() + "--> fail");
        }
    }
}
